//////////////////////////////////////////////////////////////////////////////////////////////
//	File			:	"AnimationManager.cpp"
//
//	Author			:	Mike Davis, Matt Stover, James Thornton, Keith Webster
//	
//	Project			:	TacWars
//
//	Last Modified	:	11/6/2013
//
//	Purpose			:	
//
//////////////////////////////////////////////////////////////////////////////////////////////
#include "AnimationManager.h"
#include "Animation.h"
#include "AnimInfo.h"
#include "../GameObjects/Entity.h"
#include "../StateMachine/GameplayState.h"
#include "../TinyXML/tinyxml.h"
#include "../../SGD Wrappers/SGD_String.h"
using namespace std;
#include "Frame.h"
#include "../../SGD Wrappers/CSGD_TextureManager.h"
#include "../../SGD Wrappers/CSGD_Direct3D.h"
CAnimationManager* CAnimationManager::AMInstance = nullptr;

CAnimationManager::CAnimationManager(void)
{
	Frames = nullptr;
	testEntity = nullptr;
	Animations = nullptr;
	animationInformation = nullptr;
	eventTrigger = false;
	textManager = CSGD_TextureManager::GetInstance();
	currentTime = 0;
	currentTime = GetTickCount();
}

CAnimationManager::~CAnimationManager(void)
{
}

CAnimationManager* CAnimationManager::GetInstance()
{
	if(AMInstance == nullptr)
		AMInstance = new CAnimationManager;

	return AMInstance;
}

AnimInfo* CAnimationManager::GetAnimationInfo(int VectorIndex)
{
	return oneOfEveryAnimationInGame[VectorIndex]->animationInfo;
}

int CAnimationManager::GetAMSize()
{
	return oneOfEveryAnimationInGame.size();
}

bool CAnimationManager::LoadAnimation(const char* szFilename)
{
	testEntity = new Entity;
	TiXmlDocument doc;

	string prepath = "resource/Animations/";
	prepath += szFilename;
	if(doc.LoadFile(prepath.c_str()) == false)
		return false;

	TiXmlElement* pRoot = doc.RootElement();
	if(!pRoot)
		return false;
	if(pRoot == nullptr)
		return false;


	TiXmlElement* pAnims = pRoot->FirstChildElement( "Animation" );
	int counter = 0;
	//Animation counter, how many I am at, update within Animation loop after all frames are done
	int aniCounter = 0;
	testEntity = new Entity;

	while(pAnims != nullptr)
	{
		animationInformation = new AnimInfo;
		Animations = new CAnimation;
		Animations->spriteSheetTex = -1;
		animationInformation->currAnimation = 0;
		animationInformation->currDuration = 0.0f;
		animationInformation->currFrame = 0;
		//Animation name

		//char szAniName[32];
		const char* test = "";
		char szFilePath[128];

		//Looping variable, 0 for false, 1 for true
		int aniLoopNum = 0;
		bool aniLoop = false;
		//How many frames I am loading up
		int fCount = 0;

		test = pAnims->Attribute("FilePath");
		string zxcv = "resource\\Images\\";
		zxcv += test;

		pAnims->Attribute( "IsLooping", &aniLoopNum );
		if(aniLoopNum == 0)
			aniLoop = false;
		else
			aniLoop = true;

		pAnims->Attribute( "FrameCount", &fCount );

		Animations->isLooping = aniLoop;

		const char* pFNText = pAnims->GetText();
		if( pFNText != nullptr )
			strcpy_s( szFilePath, 32, pFNText );


		animationInformation->filePath = zxcv.c_str();
		//zxcv += szFilePath;
		//animationInformation->filePath = zxcv.c_str();



		TiXmlElement* pAni = pAnims->FirstChildElement( "Frame" );
		while( pAni != nullptr)
		{
			Frames = new CFrame;
			const char* frameEvents = "";
			frameEvents = pAni->Attribute("EventName");
			string fES = frameEvents;
			int fNumber = 0;
			int APX = 0;
			int APY = 0;
			double durrTime = 0;
			int imageRectX = 0;
			int imageRectY = 0;
			int imageRectHeight = 0;
			int imageRectWidth = 0;
			int activeRectX = 0;
			int activeRectY = 0;
			int activeRectHeight = 0;
			int activeRectWidth = 0;

			pAni->Attribute( "FrameNumber", &fNumber );
			pAni->Attribute( "AnchorPointX", &APX );
			pAni->Attribute( "AnchorPointY", &APY );
			pAni->Attribute( "Time", &durrTime );
			pAni->Attribute( "iRectX", &imageRectX );
			pAni->Attribute( "iRectY", &imageRectY );
			pAni->Attribute( "iRectWidth", &imageRectWidth );
			pAni->Attribute( "iRectHeight", &imageRectHeight );
			pAni->Attribute( "ACRX", &activeRectX );
			pAni->Attribute( "ACRY", &activeRectY );
			pAni->Attribute( "ACRWidth", &activeRectWidth );
			pAni->Attribute( "ACRHeight", &activeRectHeight );
			RECT renderR = { activeRectX, activeRectY, activeRectX + activeRectWidth, activeRectY + activeRectHeight };
			RECT imageR = { imageRectX, imageRectY, imageRectWidth, imageRectHeight };

			Frames->frameCount = fNumber;
			Frames->anchorPoint.x = APX;
			Frames->anchorPoint.y = APY;
			Frames->frameDuration = (float)durrTime;
			Frames->imageRect = imageR;
			Frames->renderRect = renderR;
			Frames->Event = frameEvents;

			Animations->frameInAnimation.push_back( Frames );

			fCount++;
			pAni = pAni->NextSiblingElement( "Frame" );
		}

		TCHAR somethingweird[128];
		CSTR_TO_WSTR( somethingweird, 128, animationInformation->filePath.c_str() );
		Animations->spriteSheetTex = textManager->LoadTexture( somethingweird );
		Animations->frameNumber = fCount;
		animationInformation->currAnimation = oneOfEveryAnimationInGame.size();
		animationInformation->IsPlaying = false;
		Animations->animationInfo = animationInformation;
		testEntity->SetAnimInfo( animationInformation );
		oneOfEveryAnimationInGame.push_back( Animations );

		aniCounter++;
		counter++;
		pAnims = pAnims->NextSiblingElement ( "Animation" );
	}

	return (counter > 0);
}

void CAnimationManager::Unload(int AnimationVectorIndex)
{
	textManager->UnloadTexture( oneOfEveryAnimationInGame[AnimationVectorIndex]->spriteSheetTex );
	oneOfEveryAnimationInGame[AnimationVectorIndex]->spriteSheetTex = -1;
}

void CAnimationManager::PlayAnimation(int AnimationVectorIndex, AnimInfo &animInfo, Entity* unit)
{
	animationInformation = new AnimInfo;
	animationInformation->currAnimation = AnimationVectorIndex;
	animationInformation->filePath = animInfo.filePath;
	animationInformation->IsPlaying = true;
	animationInformation->currFrame = 0;
	animationInformation->currDuration = 0.0f;
	unit->SetAnimInfo( animationInformation );
}

void CAnimationManager::StopAnimation(int AnimationVectorIndex, AnimInfo &animInfo, Entity* unit)
{
	oneOfEveryAnimationInGame[AnimationVectorIndex]->animationInfo->IsPlaying = false;
}

void CAnimationManager::UpdateAnimation(int AnimationVectorIndex, AnimInfo &animInfo, float fElapsedTime)
{
	if(animInfo.IsPlaying == true)
	{
		animInfo.currDuration += fElapsedTime;

		if(animInfo.currDuration >= oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation[animInfo.currFrame]->frameDuration)
		{
			if(animInfo.currFrame == (float)oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation.size() - 1)
			{
				if(oneOfEveryAnimationInGame[AnimationVectorIndex]->isLooping == true)
				{
					animInfo.currFrame = 0;
				}
			}
			else if(animInfo.currFrame < (float)oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation.size() - 1)
			{
				eventTrigger = false;
				animInfo.currFrame += 1;
			}

			if(animInfo.currFrame >= (float)oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation.size()-1 && oneOfEveryAnimationInGame[AnimationVectorIndex]->isLooping == false)
				animInfo.currFrame = oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation.size() - 1;

			animInfo.currDuration = 0;
			currentTime = GetTickCount();
		}
		if(oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation[animInfo.currFrame]->Event != "")
		{
			string EventInQuestion = oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation[animInfo.currFrame]->Event;
			eventTrigger = true;
		}
	}
}

void CAnimationManager::RenderAnimation(int AnimationVectorIndex, AnimInfo &animInfo, Entity* unit)
{
	textManager->Draw(oneOfEveryAnimationInGame[AnimationVectorIndex]->spriteSheetTex, unit->GetPosX() - GameplayState::GetInstance()->GetCamX(),
		unit->GetPosY() - GameplayState::GetInstance()->GetCamY(), 1.0f, 1.0f,
		&oneOfEveryAnimationInGame[AnimationVectorIndex]->frameInAnimation[animInfo.currFrame]->renderRect);

	if(eventTrigger == true)
	{
		RECT testRect = { (LONG)unit->GetPosX(), (LONG)unit->GetPosY(), (LONG)unit->GetPosX() + 200, (LONG)unit->GetPosY() + 200 };
		CSGD_Direct3D::GetInstance()->DrawRect(testRect, D3DCOLOR_ARGB(255,255,255,0));
	}
}